import Actor from "@/Actor";
import ObjectTemplateUtil from "@/ObjectTemplateUtil";
import AbilityUtil from "@/AbilityUtil";
import AbilityButtonUtil from "@/AbilityButtonUtil";
import IconUtil from "@/IconUtil";

export default class ActorAbility extends Actor {


    abilityId?: string

    /**
     * 添加一个演员技能
     * @param actorTypeId
     * @param unit
     * @param posNum 指定技能位置
     * @param startPos 若为指定技能位置则从技能起始位置开始找到后面的空位值
     */
    constructor(actorTypeId: string, unit?: unit, posNum?: number, startPos?: number) {
        super(actorTypeId)
        if (unit == null) {
            return;
        }
        if (posNum == null) {
            if (startPos != null) {//优先从传入的startPos 开始查找空位  未传startPos 则按演员技能定义的xy当做起始位置查找空位
                posNum = ObjectTemplateUtil.getUnitAbilityTemplateNextNumber(unit, startPos)
            } else if (this.get("x") != null) {
                let basePos = AbilityButtonUtil.getNumberByPos(this.get("x"), this.get("y"))
                posNum = ObjectTemplateUtil.getUnitAbilityTemplateNextNumber(unit, basePos)
            } else {
                posNum = ObjectTemplateUtil.getUnitAbilityTemplateNextNumber(unit, 1)
            }
        }
        //
        this.unit = unit
        this.addUnitAbilityTemplate(posNum);
        //
        this.init()
        this.refresh()
    }


    set<Key extends keyof AppActorType>(key: Key, value: AppActorType[Key]) {
        super.set(key, value);
        let ability = this.getAbility();
        if (ability == null) {
            return
        }
        switch (key) {
            case "id":
                EXSetAbilityDataString(ability, 1, ABILITY_DATA_NAME, this.uuid)
                break;
            case "name":
                EXSetAbilityDataString(ability, 1, ABILITY_DATA_TIP, this.get("name"))
                break;
            case "icon":
                if (this.get("disable")) {
                    EXSetAbilityDataString(ability, 1, ABILITY_DATA_ART, IconUtil.getDisableIcon(this.get("icon")))
                } else {
                    EXSetAbilityDataString(ability, 1, ABILITY_DATA_ART, this.get("icon"))
                }
                break;
            case "disable":
                if (this.get("disable") && this.get("icon") != null) {
                    EXSetAbilityDataString(ability, 1, ABILITY_DATA_ART, IconUtil.getDisableIcon(this.get("icon")))
                }
                break;
            case "describe":
                EXSetAbilityDataString(ability, 1, ABILITY_DATA_UBERTIP, this.get("describe"))
                break;
            case "passive":
                //在其他地方判断是否是被动 然后取消释放命令
                break;
            case "hide":
                SetPlayerAbilityAvailable(GetOwningPlayer(this.unit), this.abilityId, !value);
                break;
            case "hotKey":
                EXSetAbilityDataInteger(ability, 1, ABILITY_DATA_HOTKET, char2number(this.get("hotKey")) || 0)
                break;
            case "range":
                EXSetAbilityDataReal(ability, 1, 0x6B, this.get("range"))
                break;
            case "area":
                EXSetAbilityDataReal(ability, 1, 0x6A, this.get("area"))
                break;
            case "targetType":
                AbilityUtil.setTargetType(ability, this.get("targetType"))
                break;
            case "targetAllow":
                AbilityUtil.setTargetAllow(ability, this.get("targetAllow"))
                break;
            case "dur":
                EXSetAbilityDataInteger(ability, 1, ABILITY_DATA_DUR, this.get("dur", 0))
                EXSetAbilityDataInteger(ability, 1, ABILITY_DATA_HERODUR, this.get("dur", 0))
                break;
            case "cost":
                EXSetAbilityDataInteger(ability, 1, 0x68, this.get("cost", 0))
                break;
            case "maxCd":
                EXSetAbilityDataReal(ability, 1, ABILITY_DATA_COOL, this.get("maxCd", 0))
                break;
        }
    }


    setPassive(passive: boolean) {
        this.set("passive", passive)
    }


    isPassive(): boolean {
        return this.get("passive", false)
    }


    setXY(x: number, y: number) {
        super.setXY(x, y);
        this.setAbilityPos(AbilityButtonUtil.getNumberByPos(x, y))
    }

    /**
     * 设置位置
     * @param pos
     */
    setAbilityPos(pos: number) {
        let ability = this.getAbility();
        if (ability == null) {
            return
        }
        this.removeUnitAbilityTemplate();
        this.addUnitAbilityTemplate(pos);
        this.refresh();
    }


    private addUnitAbilityTemplate(pos: number) {
        this.abilityId = ObjectTemplateUtil.addUnitAbilityTemplate(this.unit, pos);
        this.templateId = this.abilityId
        SetPlayerAbilityAvailable(GetOwningPlayer(this.unit), this.abilityId, true);
        Actor.templateIdActorMap[this.templateId] = this;
    }

    private removeUnitAbilityTemplate() {
        if (this.abilityId != null) {
            Actor.templateIdActorMap[this.templateId] = null;
            if (this.unit != null) {
                //移除技能
                ObjectTemplateUtil.removeUnitAbilityTemplate(this.unit, this.abilityId);
            }
        }

    }

    /**
     * 获取技能Handle
     */
    getAbility(): ability | null {
        if (this.abilityId != null && this.unit != null) {
            return EXGetUnitAbility(this.unit, this.abilityId);
        }
        return null
    }

    /**
     * 获取最大 maxCd
     */
    getMaxCd(): number {
        return this.get("maxCd", 0)
    }

    /**
     * 设置最大cd
     * @param maxCd
     */
    setMaxCd(maxCd: number) {
        this.set("maxCd", maxCd)
    }

    /**
     * 设置当前cd
     * @param cd
     */
    setCooldown(cd: number) {
        let ability = EXGetUnitAbility(this.unit, this.abilityId);
        EXSetAbilityState(ability, 1, cd)
    }

    /**
     * 设置当前热键
     * @param hotKey
     */
    setHotKey(hotKey: string) {
        this.set("hotKey", hotKey)
    }


    refresh() {
        super.refresh();
        let ability = this.getAbility();
        if (ability == null) {
            return
        }
        AbilityUtil.refreshAbility(this.unit, this.abilityId)
    }


    destroy() {
        super.destroy();
        this.removeUnitAbilityTemplate();
    }


    action(data?: any) {
        if (this.isPassive()) {
            return
        }
        super.action(data);
    }

}